package com.liziyi0914.morearmor.mixin;

import com.liziyi0914.morearmor.event.EventManager;
import com.liziyi0914.morearmor.event.entity.EntityClickEvent;
import com.liziyi0914.morearmor.event.entity.EntityInteractEntityEvent;
import com.liziyi0914.morearmor.event.entity.EntityInteractItemEvent;
import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket;
import net.minecraft.network.packet.c2s.play.PlayerInteractBlockC2SPacket;
import net.minecraft.network.packet.c2s.play.PlayerInteractEntityC2SPacket;
import net.minecraft.network.packet.c2s.play.PlayerInteractItemC2SPacket;
import net.minecraft.server.network.ServerPlayNetworkHandler;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.hit.HitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

/**
 * 2021/6/28<br>
 * MoreArmor<br>
 *
 * @author huanmeng_qwq
 */
@Mixin(ServerPlayNetworkHandler.class)
public abstract class ServerPlayNetworkHandlerInject {
    @Shadow
    public abstract ServerPlayerEntity getPlayer();

    @Shadow
    public ServerPlayerEntity player;

    @Inject(method = "onPlayerInteractBlock", at = @At("HEAD"))
    private void onPlayerInteractBlock(PlayerInteractBlockC2SPacket packet, CallbackInfo ci) {
        final BlockHitResult blockHitResult = packet.getBlockHitResult();
        final Hand hand = packet.getHand();
        if (blockHitResult.getType() == HitResult.Type.BLOCK) {
            if (hand == Hand.MAIN_HAND) {
                EventManager.call(new EntityClickEvent(player, false, null, blockHitResult.getBlockPos(), player.getMainHandStack(), player.isSneaking()));
            }
        }
    }

    @Inject(method = "onPlayerAction", at = @At("HEAD"))
    private void onPlayerAction(PlayerActionC2SPacket packet, CallbackInfo ci) {
        final PlayerActionC2SPacket.Action action = packet.getAction();
        final Direction direction = packet.getDirection();
        final BlockPos pos = packet.getPos();
        switch (action) {
            case RELEASE_USE_ITEM: {
                EventManager.call(new EntityClickEvent(player, false, null, pos, player.getMainHandStack(), player.isSneaking()));
            }
            case START_DESTROY_BLOCK:
            case ABORT_DESTROY_BLOCK:
            case STOP_DESTROY_BLOCK: {
                EventManager.call(new EntityClickEvent(player, true, null, pos, player.getMainHandStack(), player.isSneaking()));
            }
        }
    }


    @Inject(method = "onPlayerInteractEntity", at = @At("HEAD"))
    private void onPlayerInteractEntity(PlayerInteractEntityC2SPacket packet, CallbackInfo ci) {
        ServerWorld serverWorld = this.player.getServerWorld();
        final Entity entity = packet.getEntity(serverWorld);
        if (entity instanceof LivingEntity e) {
            EventManager.call(new EntityInteractEntityEvent(player, e, player.getMainHandStack(), packet.isPlayerSneaking()));
        }
    }

    @Inject(method = "onPlayerInteractItem", at = @At("HEAD"))
    private void onPlayerInteractItem(PlayerInteractItemC2SPacket packet, CallbackInfo ci) {
        final Hand hand = packet.getHand();
        EventManager.call(new EntityInteractItemEvent(player, hand, player.getStackInHand(hand)));
    }
}
